package com.system.job;



import com.alibaba.fastjson.JSONArray;
import com.component.domain.MJob;
import com.system.config.SpringContextUtils;
import com.system.util.ReflectUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/3/20 19:57
 * @since JDK 1.8
 * 定时任务工具
 */
@Component
@Slf4j
public class QuarztUtils {


    @Autowired
    private Scheduler scheduler;

    @Autowired
    private JobListenerServer jobListenerServer;

    private static int num=0;


    public Object execute(MJob job){
        JobConfig jobConfig= SpringContextUtils.getBean(JobConfig.class);
        String clazz= job.getMethodclazz();
        String methodname= job.getMethodname();
        Object obj=jobConfig.getJobObjectByClassName(clazz);
        log.info(clazz+"任务开始执行了");
        Object value=null;
        if(obj!=null){
            //spring执行
            if(job.getParams()!=null){
                JSONArray jsonArray= JSONArray.parseArray(job.getParams());
                Object [] args=new Object[jsonArray.size()] ;
                for (int i = 0; i < jsonArray.size(); i++) {
                    args[i]=jsonArray.get(i);
                }
                value= ReflectUtils.methodInvoke(obj,methodname,args);
            }else {
                value= ReflectUtils.methodInvoke(obj,methodname,null);
            }
        }else {
            //反射执行
            if(job.getParams()!=null){
                JSONArray jsonArray= JSONArray.parseArray(job.getParams());
                Object [] args=new Object[jsonArray.size()] ;
                for (int i = 0; i < jsonArray.size(); i++) {
                    args[i]=jsonArray.get(i);
                }
                value= ReflectUtils.methodInvoke(clazz,methodname,args);
            }else {
                value= ReflectUtils.methodInvoke(clazz,methodname,null);
            }
        }
        return value;
    }

    /**
     * 添加rest调用
     */
    public void addQuartz(MJob job){
        String clazz=job.getClazz();
        log.info("开始添加任务了{}",clazz);
        try {
            if(num==0){
                num++;
                scheduler.clear();
            }
            String timeType=job.getTimetype();
            if(QuartzTimeEnum.SECORD.getType().equals(timeType)){
                String cron=getCronSecond(job.getCron());
                job.setCron(cron);
            }else if(QuartzTimeEnum.MINUTE.getType().equals(timeType)){
                String cron=getCronMinute(job.getCron());
                job.setCron(cron);
            }else if(QuartzTimeEnum.HOUR.getType().equals(timeType)){
                String cron=getCronHour(job.getCron());
                job.setCron(cron);
            }else if(QuartzTimeEnum.DAYHOUR.getType().equals(timeType)){
                String cron=getCronHourTimeDay(job.getCron());
                job.setCron(cron);
            }else {
                return;
            }
            //添加执行监听器
            scheduler.getListenerManager().addJobListener(jobListenerServer, EverythingMatcher.allJobs());

            scheduler.start();
            JobDetail jobDetail;
            JobDataMap jobDataMap=new JobDataMap();

            jobDataMap.put("sysjob",job);

            jobDetail= JobBuilder.newJob(getClass(clazz).getClass()).withIdentity(clazz,job.getGroupName())
                        .usingJobData(jobDataMap)
                        .build();

            // 表达式调度构建器(即任务执行的时间)
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron());

            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(clazz,job.getGroupName()).withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail,trigger);
            log.info(job.getJobname()+"任务添加成功");
        }catch (Exception e){
            log.info(job.getJobname()+"添加失败 失败信息如下 "+e.getMessage());
        }
    }

    public void startAll(){
        try {
            scheduler.resumeAll();
        }catch (Exception e){
            log.info("启动失败信息如下"+e.getMessage());
            e.printStackTrace();
        }
        log.info("启动所有rest任务成功");
    }

    /**
     * 暂停所有任务
     */
    public void stopAll(){
        try {
            scheduler.pauseAll();
        }catch (Exception e){
            e.getMessage();
        }
    }


    /**
     * 执行一次
     * @param
     */
    public boolean execOne(MJob sysJob){
        try {
            if(sysJob.getType().equals("1")){
                execute(sysJob);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }



    /**
     * 任务暂停
     */
    public void stopQuarzt(MJob sysJob) {
        try {
            String clazz= sysJob.getClazz();
            String group= sysJob.getGroupName();
            scheduler.pauseJob(JobKey.jobKey(clazz,group));
            System.out.println("任务暂停成功");
            //sysJob.setStatus(1);
        }catch (Exception e){
            System.out.println("任务暂停失败");
            e.printStackTrace();
           // sysJob.setStatus(0);
        }
        //sysJob.setStatus(0);
    }



    /**
     * 任务恢复
     */
    public void startQuarzt(MJob sysJob) {
        String clazz= sysJob.getClazz();
        try {
            String group= sysJob.getGroupName();
            scheduler.resumeJob(JobKey.jobKey(clazz,group));
            System.out.println("任务启动成功");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("任务启动失败");
        }
    }

    /**
     * 任务删除
     */
    public void deleteQuarzt(MJob sysJob) {
        try {
            String group= sysJob.getGroupName();
            String clazz= sysJob.getClazz();
            scheduler.pauseTrigger(TriggerKey.triggerKey(clazz,group));  //暂停
            scheduler.unscheduleJob(TriggerKey.triggerKey(clazz,group));
            scheduler.deleteJob(JobKey.jobKey(clazz,group));
            sysJob.setStatus("3");
        }catch (Exception e){
            e.printStackTrace();
            sysJob.setStatus("1");
        }
        sysJob.setStatus("0");
    }



    /**
     * 返回类路径
     * @param
     * @return
     */
    private String returnClass(MJob sysJob){
        String clazz= sysJob.getClazz();
        String type= sysJob.getType();
        return clazz;
    }


    /**
     * 更改任务
     */
    public void updataQuarzt(MJob job) {
        try {
            String timeType=job.getTimetype();
            if(QuartzTimeEnum.SECORD.getType().equals(timeType)){
                String cron=getCronSecond(job.getCron());
                job.setCron(cron);
            }else if(QuartzTimeEnum.MINUTE.getType().equals(timeType)){
                String cron=getCronMinute(job.getCron());
                job.setCron(cron);
            }else if(QuartzTimeEnum.HOUR.getType().equals(timeType)){
                String cron=getCronHour(job.getCron());
                job.setCron(cron);
            }else if(QuartzTimeEnum.DAYHOUR.getType().equals(timeType)){
                String cron=getCronHourTimeDay(job.getCron());
                job.setCron(cron);
            }else {
                return;
            }

            String group=job.getGroupName();
            String cron=job.getCron();
            String clazz=job.getClazz();

            TriggerKey triggerKey = TriggerKey.triggerKey(clazz,group);
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    private static QuartzJobBean getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (QuartzJobBean) class1.newInstance();
    }


    /**
     * 执行分钟
     * @param time
     * @return
     */
    private String getCronMinute(String time){
        return "0 */"+time+" * * * ?";
    }

    /**
     * 执行秒
     * @param time
     * @return
     */
    private String getCronSecond(String time){
        return "0/"+time+" * * * * ?";
    }

    /**
     * 执行小时
     * @param time
     * @return
     */
    private String getCronHour(String time){
        return "0 0 */"+time+" * * ?";
    }

    /**
     * 每天固定几点执行
     * @param time
     * @return
     */
    private String getCronHourTimeDay(String time){
        return "0 0 "+time+" * * ?";
    }

    /**
     * 每月的某日 某点 执行
     * @param day  当月的某一天
     * @param time  当天的某一小时
     * @return
     */
    private String getCronDayTimeMouth(String day,String time){
        return "0 0 "+day+" "+time+" * ?";
    }
}
